<?php

namespace Xrfg\Api\Trading\Spot\Listeners;

use Carbon\Carbon;
use Throwable;
use Xrfg\Api\Trading\Spot\Events\Kline1SavedEvent;
use Xrfg\Core\Trading\Spot\Models\Kline;
use Xrfg\Core\Trading\Spot\Models\Pair;

class SaveTicker
{
    protected $redis;

    public function __construct()
    {
        $this->redis = app('redis.connection');
    }

    public function handle(Kline1SavedEvent $event)
    {
        $symbol = $event->symbol;
        $key = "etf:ticker:{$symbol}";

        $first_kline = (new Kline($symbol, 1))->first();
        //上一次的行情数据
        $ticker_old = json_decode($this->redis->get($key), true);
        //这一次行情数据的起始时间
        $openTime = Carbon::now()->subDay()->timestamp;
        //上一次行情数据的起始时间
        $old_openTime = Carbon::now()->subDay()->subMinute()->timestamp;
        //上一次行情数据的第一分钟的k线数据
        $k_old_first = (new Kline($symbol, 1))
            ->where('time_open', '>=', $old_openTime)
            ->first();
        //新加入的k线数据
        $k_last = (new Kline($symbol, 1))
            ->orderBy('time_open', 'desc')
            ->first();
        try {
            /** @var Pair $this */
            $open = (new Kline($symbol, 1))
                ->where('time_open', '>=', $openTime)
                ->orderBy('time_open', 'asc')
                ->value('price_open') ?: '0.00000000';
        } catch (Throwable $exception) {
            $open = '0.00000000';
        }

        try {
            /** @var Pair $this */
            $close = (new Kline($symbol, 1))
                ->orderBy('time_open', 'desc')
                ->value('price_close') ?: '0.00000000';
        } catch (Throwable $exception) {
            $close = '0.00000000';
        }

        try {
            if (!$ticker_old) {
                /** @var Pair $this */
                $twentyFourHours = (new Kline($symbol, 1))
                    ->where('time_open', '>=', $openTime)
                    ->orderBy('time_open', 'desc')
                    ->get();

                $high = $twentyFourHours->max('price_high') ?: '0.00000000';
                $low = $twentyFourHours->min('price_low') ?: '0.00000000';
                $number = number_format($twentyFourHours->sum('trades_number'), 8, '.', '');
                $total = number_format($twentyFourHours->sum('trades_total'), 8, '.', '');
            } else {
                //如果上一次行情的开盘价不等于最高价，再去比较新加的一条k线的最高价
                if ($k_old_first->price_high != $ticker_old['high']) {
                    $high = $ticker_old['high'] > $k_last->price_high ? $ticker_old['high'] : $k_last->price_high;
                } else {
                    $twentyFourHours = (new Kline($symbol, 1))
                        ->where('time_open', '>=', $openTime)
                        ->orderBy('time_open', 'desc')
                        ->get();
                    $high = $twentyFourHours->max('price_high') ?: '0.00000000';
                }
                //如果上一次行情的开盘价不等于最低价，再去比较新加的一条k线的最低价
                if ($k_old_first->price_low != $ticker_old['low']) {
                    $low = $ticker_old['low'] < $k_last->price_low ? $ticker_old['low'] : $k_last->price_low;
                } else {
                    $twentyFourHours = (new Kline($symbol, 1))
                        ->where('time_open', '>=', $openTime)
                        ->orderBy('time_open', 'desc')
                        ->get();
                    $low = $twentyFourHours->min('price_low') ?: '0.00000000';
                }
                /** @var Pair $this */
                if($first_kline){
                    $carbon = Carbon::parse ($first_kline['time_open']); // 格式化一个时间日期字符串为 carbon 对象
                    $int = (new Carbon)->diffInMinutes($carbon, true); // $int 为正负数
                    if($int > 24 * 60){
                        $number = $ticker_old['number'] - $k_old_first['trades_number'];
                        $total = $ticker_old['total'] - $k_old_first['trades_total'];
                    }else{
                        $number = $ticker_old['number'];
                        $total = $ticker_old['total'];
                    }
                }else{
                    $number = $ticker_old['number'];
                    $total = $ticker_old['total'];
                }

                $number = number_format($number, 8, '.', '');
                $total = number_format($total, 8, '.', '');

            }
        } catch (Throwable $exception) {
            \Log::error($exception->getMessage());
            $high = '0.00000000';
            $low = '0.00000000';
            $number = '0.00000000';
            $total = '0.00000000';
        }
        $ticker = compact('open', 'close', 'high', 'low', 'number', 'total');
        $this->redis->set($key, json_encode($ticker));
    }
}
